package ldh.im.fxbase.service;

import javafx.application.Platform;
import javafx.beans.property.LongProperty;
import javafx.beans.property.SimpleLongProperty;
import ldh.im.fxbase.util.DialogUtil;
import ldh.im.fxbase.util.FxThreadUtil;
import ldh.im.fxbase.util.ThreadPoolUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.sound.sampled.*;
import java.io.File;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.function.Consumer;

public abstract class AudioService {

    private static final Logger LOGGER = LoggerFactory.getLogger(AudioService.class);

    protected AudioFormat audioFormat;
    protected TargetDataLine targetDataLine;
    protected FloatControl ctrl;  // 音量控制器
    protected boolean flag = false;  // 录制声音运行状态
    protected int recordTotalTime = 60; // 默认录制最长60 秒
    protected LongProperty recordTimeProperty = new SimpleLongProperty(0);

    protected String saveDir;
    protected String audioFile;

    public void stopRecord() {
        flag = false;
        targetDataLine.stop();
        targetDataLine.close();
    }

    public void startRecord() {
        try {
            // 获得指定的音频格式
            audioFormat = getAudioFormat();
            DataLine.Info dataLineInfo = new DataLine.Info(TargetDataLine.class, audioFormat);
            targetDataLine = (TargetDataLine) AudioSystem.getLine(dataLineInfo);
            while(targetDataLine == null) {
                Thread.sleep(10);
                targetDataLine = (TargetDataLine) AudioSystem.getLine(dataLineInfo);
            }
            flag = true;
            recordTimeProperty.setValue(0);
            ThreadPoolUtil.submit(getAudioRecordThread());
        } catch (Exception e) {
            DialogUtil.alert("错误", "无法获取拾音器");
            LOGGER.error("初始化声音器失败", e);
        }
    }

    public abstract void playRecord(String file, Consumer<Void> consumer);

    protected abstract Runnable getAudioRecordThread();

    public boolean isNoAudio(byte[] bytes, int length, int weight) {
        if (Math.abs(bytes[length - 1]) <= weight) {
            return true;
        }
        return false;
    }

    // 获取录制声音的毫秒数
    public long getRecordTime() {
        return recordTimeProperty.get();
    }

    public LongProperty getRecordTimeProperty() {
        return recordTimeProperty;
    }

    protected String getFileName() {
        Date now = new Date();
        DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmssS");
        return dateFormat.format(now);
    }

    public String getAudioFile() {
        return audioFile;
    }

    public abstract AudioFormat getAudioFormat();

    protected void initDir() {
        File dirFile = new File(this.saveDir);
        if (!dirFile.exists()) {
            dirFile.mkdirs();
        }
    }

    protected void changeTime(long time) {
        FxThreadUtil.runLater(()->recordTimeProperty.set(time));
    }
}
